package edu.ustb.mis.dm.model.attributes.impl;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.UnhandledException;
import edu.ustb.mis.dm.model.attributes.interfaces.BinaryAttributes;

/**
 * 主要是对于BitSet封装后的扩展， 主要包括toIntArray,toIntList,toIntSet三个导出方式以及以int[] 和Collection<Integer>形式的属性导入功能。
 * 
 * @author Saya
 * @version 0.1
 */
public class BinaryAttributesImpl implements Cloneable, Serializable, BinaryAttributes<Integer, Boolean> {
	private static final long serialVersionUID = -563099304182056765L;

	/**
	 * 被包装的BitSet
	 */
	protected BitSet contents;

	private static final String EXCEPTION_MESSAGE = "未处理到的异常。";

	/**
	 * 创建一个twoStateAttributesImpl
	 */
	public BinaryAttributesImpl() {
		this.contents = new BitSet();
	}

	/**
	 * 创建一个TwoStateAttributesImpl实例，以c中元素为初始化属性id
	 * 
	 * @param c
	 * @author saya 2011-5-21
	 */
	public BinaryAttributesImpl(Collection<Integer> c) {
		if (null == c) {
			throw new IllegalArgumentException();
		}
		this.contents = new BitSet();
		for (Integer i : c) {
			if (null == i || i < 0) {
				throw new IllegalArgumentException();
			}
			this.contents.set(i);
		}
	}

	/**
	 * 创建一个TwoStateAttributesImpl实例，以indexs中元素为初始化属性id
	 * 
	 * @param c
	 * @author saya 2011-5-21
	 */
	public BinaryAttributesImpl(Integer[] indexs) {
		if (null == indexs) {
			throw new IllegalArgumentException();
		}
		this.contents = new BitSet();
		for (Integer i : indexs) {
			if (null == i || i < 0) {
				throw new IllegalArgumentException();
			}
			this.contents.set(i);
		}
	}

	/**
	 * 创建一个位 twoStateAttributesImpl,并设置其包装的BitSet，仅限内部使用
	 * 
	 * @param bitSet
	 */
	private BinaryAttributesImpl(final BitSet bitSet) {
		this.contents = bitSet;
	}

	/**
	 * 创建一个位 twoStateAttributesImpl，它的初始大小足以显式n个属性
	 * 
	 * @param n
	 */
	public BinaryAttributesImpl(final int n) {
		this.contents = new BitSet(n);
	}

	/**
	 * 添加index属性
	 */
	public boolean add(final Integer index) {
		try {
			this.contents.set(index);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 增加或删除指定属性
	 */
	public boolean add(final Integer index, final Boolean value) {
		try {
			this.contents.set(index, value);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 增加Collection中指定属性
	 */
	public boolean addAll(final Collection<Integer> c) {
		return addAll(c, true);
	}

	/**
	 * 增加或删除Collection中指定属性
	 */
	public boolean addAll(final Collection<Integer> c, final Boolean value) {
		if (null == c) return false;
		for (final Integer index : c) {
			if (null == index || index < 0 || null == value) {
				return false;
			}
		}
		for (final Integer index : c) {
			this.contents.set(index, value);
		}
		return true;
	}

	/**
	 * 增加 fromIndex（包括）到指定的 toIndex（不包括）范围内的属性。
	 */
	public boolean addAll(final Integer fromIndex, final Integer toIndex) {
		return addAll(fromIndex, toIndex, true);
	}

	/**
	 * 增加 fromIndex（包括）到指定的 toIndex（不包括）范围内的属性值为value。
	 */
	public boolean addAll(final Integer fromIndex, final Integer toIndex, final Boolean value) {
		try {
			this.contents.set(fromIndex, toIndex, value);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 增加int[]中指定属性
	 */
	public boolean addAll(final Integer[] indexs) {
		return addAll(indexs, true);
	}

	/**
	 * 增加或删除int[]中指定属性
	 */
	public boolean addAll(final Integer[] indexs, final Boolean value) {
		for (final Integer index : indexs) {
			if (null == index || index < 0 || null == value) return false;
		}
		for (final Integer index : indexs) {
			this.contents.set(index, value);
		}
		return true;
	}

	/**
	 * 对此 TwoStateAttributes 和 target 属性取交集
	 */
	public void and(final BinaryAttributes<Integer, Boolean> target) throws NullPointerException {
		this.contents.and( ((BinaryAttributesImpl)target).contents);
	}

	/**
	 * 清除此 TwoStateAttributes 和 target 中相同的属性
	 */
	public void andNot(final BinaryAttributes<Integer, Boolean> target) throws NullPointerException {
		this.contents.andNot( ((BinaryAttributesImpl)target).contents);
	}

	/**
	 * 通过反射调用BitSet的checkInvariants() 方法
	 */
	private void checkInvariants() {
		try {
			final Method method = BitSet.class.getDeclaredMethod("checkInvariants");
			method.setAccessible(true);
			method.invoke(this.contents);
		} catch (final SecurityException e) {
			e.printStackTrace();
		} catch (final NoSuchMethodException e) {
			e.printStackTrace();
		} catch (final IllegalArgumentException e) {
			e.printStackTrace();
		} catch (final IllegalAccessException e) {
			e.printStackTrace();
		} catch (final InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 清空属性集合
	 */
	public boolean clear() {
		this.contents.clear();
		return true;
	}

	/**
	 * 克隆此 TwoStateAttributesImpl，生成一个与之相等的新 TwoStateAttributesImpl。
	 */
	@Override
	public Object clone() {
		try {
			final BinaryAttributesImpl result = (BinaryAttributesImpl)super.clone();
			result.contents = (BitSet)this.contents.clone();
			return result;
		} catch (final CloneNotSupportedException e) {
			throw new InternalError();
		}
	}

	/**
	 * 查看集合是否包含指定属性
	 * 
	 * @param indexs
	 * @return
	 */
	public boolean contains(final Integer index) {
		try {
			return this.contents.get(index);
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 查看集合是否包含指定所有属性
	 * 
	 * @param indexs
	 * @return
	 */
	public boolean containsAll(final Collection<Integer> c) {
		try {
			for (final int i : c) {
				if (!this.contains(i)) {
					return false;
				}
			}
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 查看集合是否包含指定所有属性
	 * 
	 * @param indexs
	 * @return
	 */
	public boolean containsAll(final Integer[] indexs) {
		try {
			for (final int i : indexs) {
				if (!this.contains(i)) {
					return false;
				}
			}
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 将此对象与指定的对象进行比较。
	 */
	@Override
	public boolean equals(final Object obj) {
		if (! (obj instanceof BinaryAttributesImpl)) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		final BinaryAttributesImpl twoStateAttributesImpl = (BinaryAttributesImpl)obj;
		return this.contents.equals(twoStateAttributesImpl.contents);
	}

	/**
	 * 将属性集合的某个属性置为相反的值，比如index=2，对属性集来说，如果有2号属性，则删除，如果没有则增加
	 */
	public boolean flip(final Integer index) {
		try {
			this.contents.flip(index);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 将属性集合中指定的 fromIndex（包括）到指定的 toIndex（不包括）范围内的每个的属性置为相反的值， 比如fromIndex=2，toIndex=5,则对属性集2到4号属性进行有->无，无->有的操作
	 */
	public boolean flip(final Integer fromIndex, final Integer toIndex) {
		try {
			this.contents.flip(fromIndex, toIndex);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 反转所有属性
	 * 
	 * @param c
	 */
	public boolean flipAll(final Collection<Integer> c) {
		if (null == c) return false;
		for (Integer i : c) {
			if (null == i || i < 0) return false;
		}
		for (final int i : c) {
			this.contents.flip(i);
		}
		return true;
	}

	/**
	 * @param indexs 反转所有属性
	 */
	public boolean flipAll(final Integer[] indexs) {
		if (null == indexs) return false;
		for (Integer i : indexs) {
			if (null == i || i < 0) return false;
		}
		for (final int i : indexs) {
			this.contents.flip(i);
		}
		return true;
	}

	/**
	 * 返回指定属性的值,对于不存在的位置和不存在的值统一返回false
	 */
	public Boolean get(final Integer index) {
		try {
			return this.contents.get(index);
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 返回一个新的 TwoStateAttributes，它由此 TwoStateAttributes 中从 fromIndex（包括）到 toIndex（不包括）范围内的属性组成。
	 */
	public BinaryAttributes<Integer, Boolean> get(final Integer fromIndex, final Integer toIndex) throws IndexOutOfBoundsException, NullPointerException {
		if (fromIndex > toIndex) {
			throw new IndexOutOfBoundsException("fromIndex must more than toIndex");
		}
		final BitSet contents = this.contents.get(0, toIndex);
		contents.set(0, fromIndex, false);
		return new BinaryAttributesImpl(contents);
	}

	/**
	 * 返回此 TwoStateAttributes 的hashCode。
	 */
	@Override
	public int hashCode() {
		return this.contents.hashCode();
	}

	/**
	 * 如果 taget 和 当前属性集合具有相同属性，则返回true
	 */
	public boolean intersects(final BinaryAttributes<Integer, Boolean> target) {
		try {
			return this.contents.intersects( ((BinaryAttributesImpl)target).contents);
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 如果此 TwoStateAttributes 中没有包含任何属性，则返回 ture。
	 */
	public boolean isEmpty() {
		return this.contents.isEmpty();
	}

	/**
	 * 返回 fromIndex 后第一个设置为 false 的位的属性。
	 */
	public Integer nextClearBit(final Integer fromIndex) throws IndexOutOfBoundsException, NullPointerException {
		return this.contents.nextClearBit(fromIndex);
	}

	/**
	 * 返回 fromIndex 第一个设置为 true 的位的属性。 比如fromIndex=4，如果4具有属性4则返回死，如不具有属性4，而气候最小编号属性为7，那么返回7
	 */
	public Integer nextSetBit(final Integer fromIndex) throws IndexOutOfBoundsException, NullPointerException {
		return contents.nextSetBit(fromIndex);
	}

	/**
	 * 对此 TwoStateAttributes 和 target 属性取并集
	 */
	public void or(final BinaryAttributes<Integer, Boolean> target) throws IndexOutOfBoundsException, NullPointerException {
		contents.or( ((BinaryAttributesImpl)target).contents);
	}

	/**
	 * 删除指定属性
	 */
	public boolean remove(final Integer index) {
		try {
			this.contents.clear(index);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 删除自fromIndex（包括）到指定的 toIndex（不包括）的属性。
	 */
	public boolean remove(final Integer fromIndex, final Integer toIndex) {
		try {
			this.contents.clear(fromIndex, toIndex);
			return true;
		} catch (NullPointerException npe) {
			return false;
		} catch (IndexOutOfBoundsException iobe) {
			return false;
		} catch (Exception e) {
			throw new UnhandledException(EXCEPTION_MESSAGE, e.getCause());
		}
	}

	/**
	 * 删除所有属性
	 */
	public boolean removeAll() {
		return this.clear();
	}

	/**
	 * 删除Collection<Integer>内所有属性,若删除就全部删除，若失败就全部还在，属于事务性的。
	 */
	public boolean removeAll(final Collection<Integer> c) {
		if (null == c) {
			return false;
		}
		for (final Integer i : c) {
			if (null == i || i < 0) {
				return false;
			}
		}
		for (final int i : c) {
			this.contents.clear(i);
		}
		return true;
	}

	/**
	 * 删除int[]内所有属性，若删除就全部删除，若失败就全部还在，属于事务性的。
	 */
	public boolean removeAll(final Integer[] indexs) {
		if (null == indexs) {
			return false;
		}
		for (final Integer i : indexs) {
			if (null == i || i < 0) {
				return false;
			}
		}
		for (final int i : indexs) {
			this.contents.clear(i);
		}
		return true;
	}

	/**
	 * bitSet中返回的是当前对象占内存位数 在此统一返回TwoStateAttributes 的属性数目，即BitSet.cardinality()的值 为避免歧义，屏蔽了BitSet.length()和BitSet.cardinality()方法
	 */
	public int size() {
		return this.contents.cardinality();
	}

	/**
	 * 以int[]形式返回TwoStateAttributes中存在的属性
	 */
	public int[] toIntArray() {
		checkInvariants();
		int[] array = new int[]{};
		int i = nextSetBit(0);
		if (i != -1) {
			array = ArrayUtils.add(array, i);
			for (i = nextSetBit(i + 1); i >= 0; i = nextSetBit(i + 1)) {
				final int endOfRun = nextClearBit(i);
				do {
					array = ArrayUtils.add(array, i);
				} while (++i < endOfRun);
			}
		}
		return array;
	}

	/**
	 * 以List<Integer>形式返回TwoStateAttributes中存在的属性
	 */
	public List<Integer> toIntList() {
		checkInvariants();
		final List<Integer> list = new ArrayList<Integer>();
		int i = nextSetBit(0);
		if (i != -1) {
			list.add(i);
			for (i = nextSetBit(i + 1); i >= 0; i = nextSetBit(i + 1)) {
				final int endOfRun = nextClearBit(i);
				do {
					list.add(i);
				} while (++i < endOfRun);
			}
		}
		return list;
	}

	/**
	 * 以Set<Integer>形式返回TwoStateAttributes中存在的属性
	 */
	public Set<Integer> toIntSet() {
		checkInvariants();
		final Set<Integer> set = new HashSet<Integer>();
		int i = nextSetBit(0);
		if (i != -1) {
			set.add(i);
			for (i = nextSetBit(i + 1); i >= 0; i = nextSetBit(i + 1)) {
				final int endOfRun = nextClearBit(i);
				do {
					set.add(i);
				} while (++i < endOfRun);
			}
		}
		return set;
	}

	/**
	 * 返回此位 TwoStateAttributes 的字符串表示形式。
	 */
	@Override
	public String toString() {
		return this.contents.toString();
	}

	/**
	 * 对此 TwoStateAttributes 和 target 取不同属性
	 */
	public void xor(final BinaryAttributes<Integer, Boolean> target) throws NullPointerException {
		this.contents.xor( ((BinaryAttributesImpl)target).contents);
	}
}
